// 本文件实现LpPacketFragmentHeader组件
// @Author: zhengqi Wu
// @Description:
// @Version: 1.0.0
// @Date: 2021/3/23 20:55
// @Copyright: MIN-Group；国家重大科技基础设施——未来网络北大实验室；深圳市信息论与未来网络重点实验室
//

const encoding = require('../encoding')
const {TlvComponentBase} = require('./TlvComponentBase')
const LpPacketFragmentId = require('./LpPacketFragmentId').LpPacketFragmentId
const LpPacketFragmentNum = require('./LpPacketFragmentNum').LpPacketFragmentNum
const LpPacketFragmentSeq = require('./LpPacketFragmentSeq').LpPacketFragmentSeq
var aggregation = require('../common/aggregation')//实现了多继承

class LpPacketHeader extends aggregation(TlvComponentBase,encoding.SelfEncodingBase){
    constructor() {
        super();
        this.LpPacketFragmentId = new LpPacketFragmentId()
        this.LpPacketFragmentNum = new LpPacketFragmentNum()
        this.LpPacketFragmentSeq = new LpPacketFragmentSeq()
    }

    /**
     * @description 将 LpPacketHeader 线速编码为一个 TLV
     * @param enc
     * @returns {number}
     */
    wireEncode(enc){
        let totalLength = 0
        // 编码 TLV-VALUE
        // seq
        try{
            let tmpLen = this.LpPacketFragmentSeq.wireEncode(enc)
            totalLength += tmpLen

            // num
            tmpLen = this.LpPacketFragmentNum.wireEncode(enc)
            totalLength += tmpLen

            // id
            tmpLen = this.LpPacketFragmentId.wireEncode(enc)
            totalLength += tmpLen

            // 编码 TLV-LENGTH
            tmpLen = enc.prependVarNumber((totalLength))
            totalLength += tmpLen

            // 编码 TLV-TYPE
            tmpLen = enc.prependVarNumber((encoding.tlv.ComponentType.TlvLpPacketHeader))
            totalLength += tmpLen

            return totalLength
        }catch (e){
            throw e
        }

    }

    /**
     * @description 从 TLV Block 中解码出一个 LpPacketHeader
     * @param block
     */
    wireDecode(block){
        // 检查 Type 是否正确
        // getType => vlint
        try {
            if(encoding.tlv.expectType(block.getType(), (encoding.tlv.ComponentType.TlvLpPacketHeader))){
                block.parseSubElements()
                let elements = block.getSubElements()
                for(let i = 0; i < elements.length; i++){
                    let element = elements[i]
                    switch (Number(element.getType())) {
                        case encoding.tlv.ComponentType.TlvLpPacketFragmentId:
                            this.LpPacketFragmentId.wireDecode(element)
                            break
                        case encoding.tlv.ComponentType.TlvLpPacketFragmentNum:
                            this.LpPacketFragmentNum.wireDecode(element)
                            break
                        case encoding.tlv.ComponentType.TlvLpPacketFragmentSeq:
                            this.LpPacketFragmentSeq.wireDecode(element)
                            break
                    }
                }
            }
        }catch (e){
            throw e
        }
    }
}

module.exports = {
    LpPacketHeader:LpPacketHeader
}
